function momenyFormat(num) {
	num = Number(num)
	if (isNaN(num)) return '0.00'
	return num.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
}
/**
 * 筛选数组中指定字段都不为空的对象
 * @param {Array} arr - 要筛选的数组
 * @param {Array} fields - 需要检查的字段列表
 * @returns {Array} 包含指定字段都不为空的对象的新数组
 * // 使用示例
const arr = [
    {
        comboName: "",
        saleNum: "",
        type: 2,
        typeList1: [],
        typeList2: new Array(36),
        typeList3: [],
        typeName: "午餐",
        unit: "",
        unitName: ""
    },
    {
        comboName: "TAOCAN1",
        saleNum: "22",
        type: 2,
        typeList1: [],
        typeList2: new Array(36),
        typeList3: [],
        typeName: "午餐",
        unit: "",
        unitName: ""
    }
];

// 筛选 comboName 和 saleNum 都不为空的对象
const result = filterNonEmptyFields(arr, ['comboName', 'saleNum']);
console.log(result); 
// 输出：[{ comboName: "TAOCAN1", saleNum: "22", ... }]
// 只返回第二个对象，因为它的两个字段都有值
 */
function filterNonEmptyFields(arr, fields) {
	// 检查输入是否有效
	if (!Array.isArray(arr) || !Array.isArray(fields) || fields.length === 0) {
		return [];
	}

	// 筛选出指定字段全部不为空的对象
	return arr.filter(item => {
		// 检查当前对象的所有指定字段是否都不为空
		return fields.every(field => {
			// 字段不存在视为空
			if (!Object.prototype.hasOwnProperty.call(item, field)) {
				return false;
			}
			const value = item[field];
			// 不为空的条件：不是空字符串、不是null、不是undefined
			return value !== '' && value !== null && value !== undefined;
		});
	});
}
// 对象数组去重
function uniqueMultiPropertyArray(arr) {
	const uniqueArr = arr.filter((item, index, self) => {
		return index === self.findIndex(obj => obj.Id === item.Id && obj.cCusName === item.cCusName);
	});

	return uniqueArr
}
/**
 * 对对象数组进行去重操作
 * @param {Array} arr 要去重的对象数组
 * @param {String|Array} fields 用于判断重复的字段，可以是单个字段名或多个字段名组成的数组
 * @returns {Array} 去重后的新数组
 */
function uniqueArray(arr, fields) {
    // 验证输入参数
    if (!Array.isArray(arr)) {
        throw new Error('第一个参数必须是数组');
    }
    
    // 处理字段参数，统一转为数组形式
    let uniqueFields = [];
    if (typeof fields === 'string') {
        uniqueFields = [fields];
    } else if (Array.isArray(fields) && fields.length > 0) {
        uniqueFields = fields.filter(field => typeof field === 'string');
        if (uniqueFields.length === 0) {
            throw new Error('字段数组必须包含至少一个字符串类型的字段名');
        }
    } else {
        throw new Error('第二个参数必须是字符串或包含至少一个字段名的数组');
    }
    
    const seen = new Set();
    const result = [];
    
    for (const item of arr) {
        // 跳过非对象元素
        if (Object.prototype.toString.call(item) !== '[object Object]') {
            // 对于非对象元素，直接判断是否已存在
            const key = JSON.stringify(item);
            if (!seen.has(key)) {
                seen.add(key);
                result.push(item);
            }
            continue;
        }
        
        // 生成唯一标识键，基于指定的字段
        let key = '';
        for (const field of uniqueFields) {
            // 使用JSON.stringify确保不同类型的值能正确区分
            key += JSON.stringify(item[field]) + '|';
        }
        
        // 如果是新的唯一标识，则添加到结果数组
        if (!seen.has(key)) {
            seen.add(key);
            result.push(item);
        }
    }
    
    return result;
}

/**
 * 验证数组及其对象字段是否符合条件
 * @param {Array} arr - 需要验证的数组
 * @param {string|string[]} requiredFields - 必须存在且非空的字段名或字段名数组
 * @param {string|string[]} [nonEmptyObjectFields=[]] - 必须为非空对象的字段名或字段名数组
 * @param {boolean} [strictEmpty=true] - 是否严格检查空值（包括0、false等有意义的值）
 * @returns {boolean} - 所有条件满足返回true，否则返回false
 
 
 // 示例用法
 const listItem = [
   {
     comboCode: "",      // 空
     foodCode: "CP250724968",
     foodDish: {},       // 空对象
     foodId: 126,
     foodName: "",       // 空
     type: "2",
     typeName: "配菜"
   },
   {
     comboCode: "",      // 空
     foodCode: "CP250724968",
     foodDish: {},       // 空对象
     foodId: 126,
     foodName: "",       // 空
     type: "2",
     typeName: "配菜"
   }
 ];
 
 // 验证foodCode和type字段非空
 console.log(validateArray(listItem, ["foodCode", "type"])); // true
 
 // 验证foodCode和foodName字段非空（foodName为空，返回false）
 console.log(validateArray(listItem, ["foodCode", "foodName"])); // false
 
 // 验证foodDish是否为非空对象（foodDish是空对象，返回false）
 console.log(validateArray(listItem, ["foodCode"], ["foodDish"])); // false
 
 // 宽松模式：0不视为空
 console.log(validateArray([{ count: 0 }], "count", [], false)); // true
 */

function validateArrayFields(arr, requiredFields, nonEmptyObjectFields = [], strictEmpty = true) {
	// 检查数组是否存在或为空
	if (!arr || arr.length === 0) {
		return false;
	}

	// 将单个字段名转换为数组
	const requiredList = Array.isArray(requiredFields) ? requiredFields : [requiredFields];
	const nonEmptyObjList = Array.isArray(nonEmptyObjectFields) ? nonEmptyObjectFields : [nonEmptyObjectFields];

	// 遍历数组中的每个对象
	for (const obj of arr) {
		// 检查必需字段是否存在且非空
		for (const field of requiredList) {
			const value = obj[field];

			// 判断字段是否为空
			const isEmpty = strictEmpty ?
				!value // 严格模式：0、false、''、null、undefined等都视为空
				:
				value === undefined || value === null || value === ''; // 宽松模式：只检查常见空值

			if (isEmpty) {
				return false; // 任何必需字段为空，验证失败
			}
		}

		// 检查特定字段是否为非空对象
		for (const field of nonEmptyObjList) {
			const value = obj[field];

			// 判断是否为非空对象
			const isValidObject =
				typeof value === 'object' &&
				value !== null &&
				!Array.isArray(value) &&
				Object.keys(value).length > 0;

			if (!isValidObject) {
				return false; // 任何对象字段不是非空对象，验证失败
			}
		}
	}

	// 所有条件满足
	return true;
}

/**
let fieldsToCheck = ['comboName','saleNum'];
let result = checkFieldsAndGetIndices(list, fieldsToCheck);
console.log(result);
// 判断数组中每个对象元素里的某一个字段或者某几个字段是否为空，只要有任何一个对象里
的某一个字段或者某几个字段为空就不行，并且返回所有为空的数组下标  */
function checkFieldsAndGetIndices(arr, fields) {
	let emptyIndices = [];
	arr.forEach((obj, index) => {
		let isEmpty = fields.some(field => {
			const value = obj[field];
			return value === null || value === undefined || value === '';
		});
		if (isEmpty) {
			emptyIndices.push(index);
		}
	});
	return emptyIndices;
}
/**
 * 判断当前时间是否在每周二12:00至周五12:00之间
 * @param {Date} [date] - 可选参数，指定要检查的日期，默认使用当前时间
 * @returns {boolean} - 如果在范围内返回true，否则返回false
 * 
// 使用示例
// console.log("当前是否在范围内：", isInTimeRange());
 */
function isInTimeRange(date) {
	// 使用提供的日期或当前日期
	const currentDate = date ? new Date(date) : new Date();

	// 获取星期几（0=星期日, 1=星期一, ..., 2=星期二, ..., 5=星期五）
	const day = currentDate.getDay();
	// 获取小时数（0-23）
	const hours = currentDate.getHours();
	// 获取分钟数（0-59）
	const minutes = currentDate.getMinutes();
	// 获取秒数（0-59）
	const seconds = currentDate.getSeconds();

	// 周二、周三、周四全天都在范围内
	if (  day === 3 || day === 4) {
		return true;
	}

	// 处理周五的情况：仅00:00:00到12:00:00之间
	if (day === 5) {
		// 小时小于12 → 在范围内
		if (hours < 12) {
			return true;
		}
		// 刚好12:00:00也视为在范围内
		if (hours === 12 && minutes === 0 && seconds === 0) {
			return true;
		}
	}
	
	if (day === 2) {
		console.log(hours)
		// 小时小于12 → 在范围内
		if (hours > 11) {
			return true;
		}
		// 刚好12:00:00也视为在范围内
		if (hours === 12 && minutes === 0 && seconds === 0) {
			return true;
		}
	}

	// 其他情况（周日、周一、周五12:00之后）均不在范围内
	return false;
}
/**
 * 将形如"2025/7/31"的日期格式化为"2025-07-31"格式
 * @param {string} dateString - 输入的日期字符串，格式为YYYY/M/D
 * @returns {string} 格式化后的日期字符串，格式为YYYY-MM-DD
 * // 使用示例
const originalDate = "2025/7/31";
const formattedDate = formatDate(originalDate);
console.log(formattedDate); // 输出: "2025-07-31"
 */
function formatDate(dateString) {
	// 分割日期字符串为年、月、日
	const [year, month, day] = dateString.split('/').map(Number);

	// 确保月份和日期为两位数（不足两位前面补0）
	const formattedMonth = String(month).padStart(2, '0');
	const formattedDay = String(day).padStart(2, '0');

	// 拼接成目标格式
	return `${year}-${formattedMonth}-${formattedDay}`;
}


/**
 * 验证值是否符合指定规则
 * @param {string|number} value - 需要验证的值
 * @param {Object} options - 验证选项配置
 * @param {boolean} [options.allowDecimal=false] - 是否允许小数点
 * @param {number|null} [options.maxLength=null] - 最大允许长度，null表示不限制
 * @param {boolean} [options.allowLetters=false] - 是否允许大小写字母
 * @param {boolean} [options.allowSpecialChars=false] - 是否允许特殊符号
 * @param {boolean} [options.allowChinese=false] - 是否允许汉字
 * @param {boolean} [options.allowZero=true] - 是否允许值为0
 * @returns {Object} 包含验证结果和错误信息的对象
 * 
// 示例用法
const testCases = [
    { 
        value: 0, 
        config: { allowZero: false } 
    },
    { 
        value: "0", 
        config: { allowZero: false }  
    },
    { 
        value: "123.45", 
        config: { allowDecimal: true, maxLength: 10 } 
    },
    { 
        value: "Hello123", 
        config: { allowLetters: true } 
    },
    { 
        value: "测试文字", 
        config: { allowChinese: true } 
    },
    { 
        value: "user@12.", 
        config: { allowDecimal:true,allowLetters: true, allowSpecialChars: true } 
    },
    { 
        value: "123456", 
        config: { maxLength: 5 } 
    }
];

// 执行测试
testCases.forEach(({ value, config }, index) => {
    const result = validateValue(value, config);
    console.log(`测试用例 ${index + 1}:`);
    console.log(`值: ${typeof value}类型的"${value}"`);
    console.log(`配置:`, config);
    console.log(`结果:`, result);
    console.log('---');
});
 */
function validateValue(value, options = {}) {
	// 处理原始值，转为字符串便于统一处理
	const originalValue = value;
	const inputStr = String(value);

	// 设置默认选项，新增allowNegative默认值为false
	const {
		allowDecimal = false,
			maxLength = null,
			allowLetters = false,
			allowSpecialChars = false,
			allowChinese = false,
			allowZero = true,
			allowNegative = false // 新增选项：是否允许负数
	} = options;

	// 检查空值  暂时注释
	// if (inputStr.trim() === '') {
	// 	return {
	// 		valid: false,
	// 		message: '值不能为空'
	// 	};
	// }
	// 检查负数（仅允许开头出现一个减号）
	if (inputStr.includes('-')) {
		// 如果不允许负数，直接返回错误
		if (!allowNegative) {
			return {
				valid: false,
				message: '不允许输入负数'
			};
		}
		// 检查减号是否只出现在开头且只出现一次
		if (inputStr.indexOf('-') !== 0 || inputStr.lastIndexOf('-') !== 0) {
			return {
				valid: false,
				message: '负数格式不正确，减号只能出现在开头且只能有一个'
			};
		}
	}

	// 检查是否为0（包括字符串"0"和数字0）
	if (!allowZero && (originalValue === 0 || inputStr === "0")) {
		return {
			valid: false,
			message: '不允许值为0'
		};
	}
	// 检查前导零（整数部分）
	const integerPart = inputStr.split('.')[0];
	if (integerPart.length > 1 && integerPart.startsWith('0')) {
		return {
			valid: false,
			message: '输入不能包含前导0'
		};
	}

	// 检查长度限制
	if (maxLength !== null && inputStr.length > maxLength) {
		return {
			valid: false,
			message: `长度不能超过${maxLength}个字符`
		};
	}

	// 定义各类字符的正则表达式
	const regexPatterns = {
		decimal: /\./,
		letter: /[a-zA-Z]/,
		chinese: /[\u4e00-\u9fa5]/,
		// 包含常见特殊符号，可根据需要调整
		specialChar: /[!@#$%^&*(),.?":{}|<>;'/\\[\]`~=+\_\s]/, 
		digit: /[0-9]/
	};

	// 检查每个字符
	for (const char of inputStr) {
		// 数字默认允许（0的整体判断已在前面处理）
		if (regexPatterns.digit.test(char)) {
			continue;
		}

		// 检查小数点
		if (regexPatterns.decimal.test(char)) {
			if (!allowDecimal) {
				return {
					valid: false,
					message: '不允许包含小数点'
				};
			}
			continue;
		}

		// 检查字母
		if (regexPatterns.letter.test(char)) {
			if (!allowLetters) {
				return {
					valid: false,
					message: '不允许包含字母'
				};
			}
			continue;
		}

		// 检查汉字
		if (regexPatterns.chinese.test(char)) {
			if (!allowChinese) {
				return {
					valid: false,
					message: '不允许包含汉字'
				};
			}
			continue;
		}

		// 检查特殊符号
		if (regexPatterns.specialChar.test(char)) {
			if (!allowSpecialChars) {
				return {
					valid: false,
					message: `不允许包含特殊符号: ${char}`
				};
			}
			continue;
		}

		// 未识别的字符
		if(!allowNegative) return {
			valid: false,
			message: `不允许包含字符: ${char}`
		};
		
	}

	return {
		valid: true,
		message: '验证通过'
	};
}
// 封装函数：返回指定位数的字符串
// 参数：str-原始字符串，length-指定的长度
// 功能：如果原字符串长度小于指定长度，补空格；如果大于，截断
// 使用示例
// console.log(getSpecifiedLengthString("hello", 10)); // "hello     "
// console.log(getSpecifiedLengthString("hello world", 5)); // "hello"
// console.log(getSpecifiedLengthString("test", 4)); // "test"
function getSpecifiedLengthString(str, length) {
	// 检查输入是否为字符串
	if (typeof str !== 'string') {
		throw new Error('第一个参数必须是字符串');
	}

	// 检查长度是否为正整数
	if (typeof length !== 'number' || length <= 0 || !Number.isInteger(length)) {
		throw new Error('第二个参数必须是正整数');
	}

	// 如果字符串长度小于指定长度，补空格
	if (str.length < length) {
		return str.padEnd(length, ' ');
	}
	// 如果字符串长度大于等于指定长度，截断
	else {
		return str.substring(0, length);
	}
}

/**
 * 验证字段是否为空 * @param {string} value - 需要验证的值
 * @param {string} value - 传入的值
 * @param {string} fieldName - 传入的字段名
 * 
 */
function checkEmpty(value, fieldName) {
	// 处理空值情况：null、undefined、空字符串（含仅空格的字符串）
	const isEmpty = value === null || value === undefined || String(value).trim() === '';

	if (isEmpty) {
		return {
			isEmpty: false,
			message: `请输入${fieldName}`
		};
	}

	return {
		isEmpty: true,
		message: ''
	};
}

/**
 * 检查数组中所有对象的指定字段是否都不为空值
 * @param {Array} arr 要检查的对象数组
 * @param {String} field 要检查的字段名
 * @returns {Boolean} 如果所有对象的指定字段都不为空则返回true，否则返回false
 */
function checkAllFieldsNotEmpty(arr, fields) {
    // 验证输入参数
       if (!Array.isArray(arr)) {
           throw new Error('第一个参数必须是数组');
       }
       if (!Array.isArray(fields) || fields.length === 0) {
           throw new Error('第二个参数必须是包含至少一个字段名的数组');
       }
       if (fields.some(field => typeof field !== 'string')) {
           throw new Error('字段名数组中的元素必须都是字符串类型');
       }
       
       // 定义空值的判断标准
       const isEmpty = (value) => {
           // null或undefined
           if (value === null || value === undefined) {
               return true;
           }
           // 空字符串（包括仅含空白字符的字符串）
           if (typeof value === 'string' && value.trim() === '') {
               return true;
           }
           // 空数组
           if (Array.isArray(value) && value.length === 0) {
               return true;
           }
           // 空对象
           if (Object.prototype.toString.call(value) === '[object Object]' && Object.keys(value).length === 0) {
               return true;
           }
           return false;
       };
       
       // 遍历数组检查每个对象
       for (let i = 0; i < arr.length; i++) {
           const item = arr[i];
           
           // 如果元素不是对象，视为无效（字段为空）
           if (Object.prototype.toString.call(item) !== '[object Object]') {
               return false;
           }
           
           // 检查当前对象的所有指定字段
           for (const field of fields) {
               if (isEmpty(item[field])) {
                   return false;
               }
           }
       }
       
       // 所有元素的所有字段检查通过
       return true;
}







/**
 * 验证手机号、邮箱、银行卡号或联行号格式 * @param {string} value - 需要验证的值
 * @param {string} type - 验证类型：'phone'|'email'|'bankCard'|'bankBranch'
 * @returns {Object} 验证结果
 *   - isValid: boolean - 是否通过验证
 *   - error: string - 错误信息（空字符串表示无错误）
 * @throws {Error} 当类型参数无效时抛出错误
 * // 使用示例
console.log(validateFormat('13800138000', 'phone'));
// { isValid: true, error: "" }

console.log(validateFormat('test@example.com', 'email'));
// { isValid: true, error: "" }

console.log(validateFormat('6222021234567890123', 'bankCard'));
// { isValid: true, error: "" }

console.log(validateFormat('102100099999', 'bankBranch'));
// { isValid: true, error: "" }

// 无效案例
console.log(validateFormat('1234567890', 'phone'));
// { isValid: false, error: "请输入有效的手机号（11位数字，以1开头）" }

console.log(validateFormat('invalid-email', 'email'));
// { isValid: false, error: "请输入有效的邮箱地址（如：example@domain.com）" }

console.log(validateFormat('123456', 'bankCard'));
// { isValid: false, error: "请输入有效的银行卡号（16-19位数字）" }
 */
function validateFormat(value, type) {
	// 处理空值情况
	const strValue = String(value).trim();
	// if (strValue === '' || value === null || value === undefined) {
	//     return {
	//         isValid: false,
	//         error: '输入不能为空'
	//     };
	// } 

	// 定义验证规则映射表
	const validators = {
		// 手机号验证：中国大陆手机号，11位数字，以1开头，第二位为3-9
		phone: {
			regex: /^1[3-9]\d{9}$/,
			error: '请输入有效的手机号（11位数字，以1开头）'
		},
		// 邮箱验证：支持字母、数字、特殊字符及多级域名
		email: {
			regex: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
			error: '请输入有效的邮箱地址（如：example@domain.com）'
		},
		// 银行卡号验证：16-19位数字（涵盖大多数银行的卡号长度）
		supplierBankNumber: {
			regex: /^\d{16,19}$/,
			error: '请输入有效的银行卡号（16-19位数字）'
		},
		// 联行号验证：12位数字（银行联行号固定长度）
		supplierInterBank: {
			regex: /^\d{12}$/,
			error: '请输入有效的联行号（12位数字）'
		},
		// 统一社会信用代码验证：18位，包含数字、大写字母
		supplierCode: {
			regex: /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/,
			error: '请输入有效的统一社会信用代码（18位字符，含数字和大写字母）'
		}
	};

	// 验证类型是否有效
	if (!validators.hasOwnProperty(type)) {
		throw new Error('无效的验证类型，可选类型：phone、email、bankCard、bankBranch');
	}

	// 执行验证
	const {
		regex,
		error
	} = validators[type];
	if (regex.test(strValue)) {
		return {
			isValid: true,
			error: ''
		};
	} else {
		return {
			isValid: false,
			error
		};
	}
}




/**
 * 根据传入的日期判断是星期几
 * @param {Date|string|number} date - 日期，可以是Date对象、日期字符串或时间戳
 * @returns {Object} 包含星期几数字和名称的对象
 * // 示例用法
const testDates = [
    new Date(),                  // 当前日期
    '2023-10-01',                // 字符串日期（国庆节）
    '2024-02-10',                // 字符串日期
    1710000000000,               // 时间戳
    'invalid-date',              // 无效日期
    999999999999999999999        // 无效时间戳
];

// 测试并输出结果
testDates.forEach((date, index) => {
    const result = getDayOfWeek(date);
    console.log(`测试用例 ${index + 1}:`);
    console.log(`输入:`, date);
    console.log(`结果:`, result);
    console.log('---');
});
 */
function getDayOfWeek(date) {
	// 处理不同类型的日期输入
	let targetDate;

	if (date instanceof Date) {
		// 如果是Date对象，直接使用
		targetDate = date;
	} else if (typeof date === 'string' || typeof date === 'number') {
		// 如果是字符串或数字，尝试转换为Date对象
		targetDate = new Date(date);
	} else {
		return {
			success: false,
			error: '无效的日期格式，请传入Date对象、日期字符串或时间戳'
		};
	}

	// 检查日期是否有效
	if (isNaN(targetDate.getTime())) {
		return {
			success: false,
			error: '无法解析为有效的日期'
		};
	}

	// 获取星期几（0表示星期日，6表示星期六）
	const dayNumber = targetDate.getDay();

	// 星期名称映射表
	const dayNames = [
		'周日',
		'周一',
		'周二',
		'周三',
		'周四',
		'周五',
		'周六'
	];

	return {
		success: true,
		dayNumber: dayNumber, // 数字形式（0-6）
		dayName: dayNames[dayNumber], // 中文名称
		date: targetDate.toLocaleDateString() // 格式化的日期字符串
	};
}

function mergeArrays(arr1, key1, insertKey, arr2, key2) {
	// 遍历数组2中的每个元素
	return arr2.map(item2 => {
		// 在数组1中查找符合条件的元素（key1值与key2值相等）
		const matchedItem = arr1.find(item1 => item1[key1] === item2[key2]);
		// 如果找到匹配元素，将数组1的insertKey字段插入数组2的元素中
		if (matchedItem) {
			return {
				...item2,
				[insertKey]: matchedItem[insertKey]
			};
		}
		// 未找到匹配元素则返回原元素
		return item2;
	});
}

module.exports = {
	momenyFormat,
	uniqueMultiPropertyArray,
	validateArrayFields,
	checkFieldsAndGetIndices,
	isInTimeRange,
	formatDate,
	filterNonEmptyFields,
	validateFormat,
	validateValue,
	getDayOfWeek,
	mergeArrays,
	getSpecifiedLengthString,
	checkEmpty,
	checkAllFieldsNotEmpty,
	uniqueArray
};